package com.zenithmind.common.utils;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;

/**
 * Bean拷贝工具类 - 重构后的版本
 * 遵循单一职责原则：专门负责Bean拷贝操作
 *
 * @author ZenithMind Team
 * @since 2025-01-09
 * @deprecated 建议直接使用 {@link BeanCopyService} 接口的实现类
 */
@Deprecated
public class BeanCopyUtils {

    // ================ 静态方法（保持向后兼容） ================

    /**
     * 单个对象拷贝
     * @deprecated 请使用 {@link BeanCopyService#copyBean(Object, Class)}
     */
    @Deprecated
    public static <T> T copyBean(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }

        try {
            T target = clazz.getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, target);
            return target;
        } catch (Exception e) {
            throw new RuntimeException("Bean拷贝失败", e);
        }
    }

    /**
     * 单个对象拷贝（使用Supplier）
     * @deprecated 请使用 {@link BeanCopyService#copyBean(Object, Supplier)}
     */
    @Deprecated
    public static <T> T copyBean(Object source, Supplier<T> supplier) {
        if (source == null) {
            return null;
        }

        T target = supplier.get();
        BeanUtils.copyProperties(source, target);
        return target;
    }

    /**
     * 列表对象拷贝
     * @deprecated 请使用 {@link BeanCopyService#copyBeanList(List, Class)}
     */
    @Deprecated
    public static <T> List<T> copyBeanList(List<?> sourceList, Class<T> clazz) {
        if (sourceList == null || sourceList.isEmpty()) {
            return new ArrayList<>();
        }

        List<T> targetList = new ArrayList<>(sourceList.size());
        for (Object source : sourceList) {
            T target = copyBean(source, clazz);
            if (target != null) {
                targetList.add(target);
            }
        }

        return targetList;
    }

    /**
     * 列表对象拷贝（使用Supplier）
     * @deprecated 请使用 {@link BeanCopyService#copyBeanList(List, Supplier)}
     */
    @Deprecated
    public static <T> List<T> copyBeanList(List<?> sourceList, Supplier<T> supplier) {
        if (sourceList == null || sourceList.isEmpty()) {
            return new ArrayList<>();
        }

        List<T> targetList = new ArrayList<>(sourceList.size());
        for (Object source : sourceList) {
            T target = copyBean(source, supplier);
            if (target != null) {
                targetList.add(target);
            }
        }

        return targetList;
    }

    /**
     * 深度拷贝对象
     * @deprecated 请使用 {@link BeanCopyService#deepCopyBean(Object, Class)}
     */
    @Deprecated
    public static <T> T deepCopyBean(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }

        try {
            T target = clazz.getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, target);
            // 这里可以添加深度拷贝逻辑，目前使用浅拷贝
            return target;
        } catch (Exception e) {
            throw new RuntimeException("深度Bean拷贝失败", e);
        }
    }

    /**
     * 拷贝对象属性（忽略null值）
     * @deprecated 请使用 {@link BeanCopyService#copyPropertiesIgnoreNull(Object, Object)}
     */
    @Deprecated
    public static void copyPropertiesIgnoreNull(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /**
     * 拷贝对象属性（忽略指定属性）
     * @deprecated 请使用 {@link BeanCopyService#copyPropertiesIgnore(Object, Object, String...)}
     */
    @Deprecated
    public static void copyPropertiesIgnore(Object source, Object target, String... ignoreProperties) {
        BeanUtils.copyProperties(source, target, ignoreProperties);
    }

    // ================ 辅助方法 ================

    /**
     * 获取对象中值为null的属性名
     */
    private static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();

        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }

        return emptyNames.toArray(new String[0]);
    }


}
